package com.jiepos.mpos.pay;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.jiepos.mpos.common.constant.RspCodeConstant;
import com.jiepos.mpos.common.constant.SystemConstant;
import com.jiepos.mpos.core.util.ContextUtils;
import com.jiepos.mpos.core.util.StringUtils;
import com.jiepos.mpos.pay.quickpay.service.IQuickPayService;

import net.sf.json.JSONObject;

public class CommonService {   
	private static final Logger _log = LoggerFactory.getLogger(CommonService.class);
    
	public static String encapRespCode(String respCd, String errorCode)  {   
		if (StringUtils.isBlank(respCd))
            return null;
        switch (respCd) {
            case SystemConstant.LAIDOUZHEN_SUCCESS:
            	return SystemConstant.RSPCODE_SUCCESS;
            case SystemConstant.EPAYPP_SUCCESS:
            	return SystemConstant.RSPCODE_SUCCESS;
            case SystemConstant.LAIDOUZHEN_UNKNOW:
            	if(SystemConstant.S0_000000.equals(errorCode)){
            		return SystemConstant.RSPCODE_XX;
            	}
            	return SystemConstant.RSPCODE_ERROR;
            case SystemConstant.EPAYPP_CLOSE:
            	return SystemConstant.RSPCODE_CLOSE;
            case SystemConstant.EPAYPP_WAIT_PAY:
            	return SystemConstant.RSPCODE_XX;
            case SystemConstant.EPAYPP_1101100100:
            	return SystemConstant.RSPCODE_ERROR;
            case SystemConstant.EPAYPP_1101109999:
            	return SystemConstant.RSPCODE_XX;
            case SystemConstant.YEEPAY_SUCCESS:
            	return SystemConstant.RSPCODE_SUCCESS;
            case SystemConstant.YEEPAY_FAIL:
            	return SystemConstant.RSPCODE_ERROR;
            case SystemConstant.YEEPAY_INIT:
            	return SystemConstant.RSPCODE_XX;
            case SystemConstant.YEEPAY_FROZEN:
            	return SystemConstant.RSPCODE_ERROR;
            case SystemConstant.YEEPAY_THAWED:
            	return SystemConstant.RSPCODE_ERROR;
            case SystemConstant.YEEPAY_REVERSE:
            	return SystemConstant.RSPCODE_ERROR;
            case SystemConstant.XKPAY_SUCCESS:
            	return SystemConstant.RSPCODE_SUCCESS;
            case SystemConstant.XKPAY_FAILED:
            	return SystemConstant.RSPCODE_ERROR;
            case SystemConstant.HUIEPAY_WAIT_BUYER_PAY:
            	return SystemConstant.RSPCODE_XX;
            case SystemConstant.HUIEPAY_TRADE_SUCCESS:
            	return SystemConstant.RSPCODE_SUCCESS;
            case SystemConstant.HUIEPAY_TRADE_CLOSED:
            	return SystemConstant.RSPCODE_CLOSE;
            case SystemConstant.HUIEPAY_TRADE_CANCEL:
            	return SystemConstant.RSPCODE_ERROR;
            case SystemConstant.HUIEPAY_TRADE_FAIL:
            	return SystemConstant.RSPCODE_ERROR;
            default:
            	return SystemConstant.RSPCODE_XX;
        }
	} 
	
	public static String encapSettleRespCode(String settleCd)  {   
		if (StringUtils.isBlank(settleCd))
            return null;
        switch (settleCd) {
            case SystemConstant.LAIDOUZHEN_SUCCESS:
            	return SystemConstant.AUDIT_STL_1;
            case SystemConstant.EPAYPP_SUCCESS:
            	return SystemConstant.AUDIT_STL_1;
            case SystemConstant.LAIDOUZHEN_UNKNOW:
            	return SystemConstant.AUDIT_STL_0;
            case SystemConstant.EPAYPP_CLOSE:
            	return SystemConstant.AUDIT_STL_0;
            case SystemConstant.EPAYPP_WAIT_PAY:
            	return SystemConstant.AUDIT_STL_0;
            case SystemConstant.YEEPAY_RECEIVED:
            	return SystemConstant.AUDIT_STL_0;
            case SystemConstant.YEEPAY_PROCESSING:
            	return SystemConstant.AUDIT_STL_0;
            case SystemConstant.YEEPAY_SUCCESSED:
            	return SystemConstant.AUDIT_STL_1;
            case SystemConstant.YEEPAY_FAILED:
            	return SystemConstant.AUDIT_STL_2;
            case SystemConstant.YEEPAY_REFUNED:
            	return SystemConstant.AUDIT_STL_2;
            case SystemConstant.YEEPAY_CANCELLED:
            	return SystemConstant.AUDIT_STL_2;
            case SystemConstant.HUIEPAY_WAIT_BUYER_PAY:
            	return SystemConstant.AUDIT_STL_0;
            case SystemConstant.HUIEPAY_TRADE_SUCCESS:
            	return SystemConstant.AUDIT_STL_1;
            case SystemConstant.HUIEPAY_TRADE_CLOSED:
            	return SystemConstant.AUDIT_STL_0;
            case SystemConstant.HUIEPAY_TRADE_CANCEL:
            	return SystemConstant.AUDIT_STL_0;
            case SystemConstant.HUIEPAY_TRADE_FAIL:
            	return SystemConstant.AUDIT_STL_0;
            default:
            	return settleCd;
        }
	}
	
	public static String encapResultCode(String resultCd)  {   
        switch (resultCd) {
        	case SystemConstant.EPAYPP_00:
        		return SystemConstant.RSPCODE_SUCCESS;
        	case SystemConstant.YEEPAY__0000:
            	return SystemConstant.RSPCODE_SUCCESS;
        	case SystemConstant.EPAYPP_1101109999:
        		return SystemConstant.EPAYPP_1101109999;
        	case SystemConstant.EPAYPP_1101100100:
        		return SystemConstant.EPAYPP_1101100100;
            default:
            	return SystemConstant.RSPCODE_ERROR;
        }
	}
	
	public static String encapStlResultCode(String stlst)  {   
        switch (stlst) {
	        case SystemConstant.YEEPAY_SUCCESSED:
	        	return SystemConstant.RSPCODE_SUCCESS;
	        case SystemConstant.YEEPAY_FAILED:
	        	return SystemConstant.RSPCODE_ERROR;
	        case SystemConstant.YEEPAY_REFUNED:
	        	return RspCodeConstant.RSPCODE_300062;
	        case SystemConstant.YEEPAY_CANCELLED:
	        	return RspCodeConstant.RSPCODE_300063;
            default:
            	return SystemConstant.RSPCODE_XX;
        }
	}
	
	public static String convertStlst(String stlst)  {   
		if (StringUtils.isBlank(stlst))
            return null;
        switch (stlst) {
            case "0":
            	return SystemConstant.AUDIT_STL_0;
            case "1":
            	return SystemConstant.AUDIT_STL_1;
            case "2":
            	return SystemConstant.AUDIT_STL_2;
            case "4":
            	return SystemConstant.AUDIT_STL_3;
            default:
            	return stlst;
        }
	} 
	/**
	 * 
	* <功能描述>请求集合转换成标准报文
	* @param payReqMap
	* @return
	* @see [类、类#方法、类#成员]
	 */
	public static Map<String,String> getStandardData(Map<String,String> payReqMap){
		Map<String,String> standardDataMap = new HashMap<String,String>();
		standardDataMap.put("loc_trace_no",payReqMap.get("loc_trace_no"));//本地流水号
		standardDataMap.put("trf_mchnt_cd",payReqMap.get("trf_mchnt_cd"));//商户编号（渠道）
		standardDataMap.put("master_key",payReqMap.get("master_key"));//主密钥
		standardDataMap.put("trf_term_id",payReqMap.get("trf_term_id"));//终端编号（渠道）
		standardDataMap.put("loc_dt",payReqMap.get("loc_dt"));//系统日期（渠道）
		standardDataMap.put("loc_ts",payReqMap.get("loc_ts"));//系统时间（渠道）
		standardDataMap.put("custom_no",payReqMap.get("custom_no"));//会员编号（支付系统）
		standardDataMap.put("login_id",payReqMap.get("login_id"));//登录id（支付系统）
		standardDataMap.put("term_id",payReqMap.get("term_id"));//终端编号（支付系统）
		standardDataMap.put("act_out_no",payReqMap.get("act_out_no"));//交易卡号
		standardDataMap.put("real_name",payReqMap.get("name"));//真实姓名
		standardDataMap.put("certificate_no",payReqMap.get("certificate_no"));//身份证号码
		standardDataMap.put("phone",payReqMap.get("phone"));//手机号码
		standardDataMap.put("bank_nm",payReqMap.get("bank_nm"));//到账卡银行名称
		standardDataMap.put("settle_acct",payReqMap.get("act_in_no"));//到账卡号
		standardDataMap.put("midfee",payReqMap.get("midfee"));//商户手续费
		standardDataMap.put("cnapsno",payReqMap.get("cnapsno"));//入账银行联行号
		standardDataMap.put("cvv2",payReqMap.get("cvv2"));//cvv2
		standardDataMap.put("exptm",payReqMap.get("crd_exp"));//有效期
		standardDataMap.put("rand",payReqMap.get("rand"));//验证码
		standardDataMap.put("pin",payReqMap.get("pin"));//密码
		standardDataMap.put("stl_type",payReqMap.get("stl_type"));//入账类型
		standardDataMap.put("trans_at",payReqMap.get("trans_at"));//交易金额
		standardDataMap.put("front_url",payReqMap.get("front_url"));//前台通知地址
		standardDataMap.put("back_url",payReqMap.get("back_url"));//后台通知地址
		standardDataMap.put("order_info",payReqMap.get("order_info"));//商品信息
		standardDataMap.put("payUrl",payReqMap.get("payUrl"));//商品信息
		standardDataMap.put("param_no",payReqMap.get("param_no"));//业务参数编号
		standardDataMap.put("bankcard_uuid",payReqMap.get("bankcard_uuid"));//银行卡主键
		standardDataMap.put("channel_No",payReqMap.get("channel_No"));//通道编号
		standardDataMap.put("verify_code",payReqMap.get("verify_code"));//手机验证码
		return standardDataMap;	
	}
	
	/**
	 * 
	* <功能描述> 多层json转map
	* @param jsonStr
	* @return
	* @see [类、类#方法、类#成员]
	 */
	public static Map<String, String> parseJsonToMap(String jsonStr, Map<String, String> dataMap) {
		// 最外层解析
		JSONObject object = JSONObject.fromObject(jsonStr);
		for (Object k : object.keySet()) {
			Object v = object.get(k);
			// 如果内层还是数组的话，继续解析
			if (v instanceof JSONObject) {
				parseJsonToMap(String.valueOf(v), dataMap);
			} else {
				dataMap.put(String.valueOf(k), String.valueOf(v));
			}
		}
		return dataMap;
	}
    
	/**
	 * 
	* <功能描述> 单json转map
	* @param jsonStr
	* @return
	* @see [类、类#方法、类#成员]
	 */
	public static Map<String, String> parseJsonToMap(String jsonStr){  
    	Map<String, String> map = new HashMap<String, String>();
         //最外层解析  
         JSONObject object = JSONObject.fromObject(jsonStr);  
         for(Object k : object.keySet()){  
               Object v = object.get(k);    
                  map.put(String.valueOf(k), String.valueOf(v));  
         }  
         return map;  
     } 
    
    /**
     * 
    * <功能描述> map转json
    * @param map
    * @return
    * @see [类、类#方法、类#成员]
     */
    public static String mapToJson(Map<String, String> map) {  
        Set<String> keys = map.keySet();  
        String key = "";  
        String value = "";  
        StringBuilder builder = new StringBuilder();  
        builder.append("{");  
        for (Iterator<String> it = keys.iterator(); it.hasNext();) {  
            key = (String) it.next();  
            value = map.get(key);  
            builder.append(key + ":" +"\""+ value+"\"");  
            if (it.hasNext()) {  
            	builder.append(",");  
            }  
        }  
        builder.append("}");  
        return builder.toString();  
    }

    
    /**
     * 
    * 功能描述:截取html中指定标签属性值
    * @param source
    * @param element
    * @param attr
    * @return
     */
	public static String match(String source, String element, String attr) throws Exception { 
		Assert.notNull(source);
		List<String> result = new ArrayList<String>();  
        String reg = "<" + element + "[^<>]*?\\s" + attr + "=['\"]?(.*?)['\"]?(\\s.*?)?>";  
        Matcher m = Pattern.compile(reg).matcher(source);  
        while (m.find()) {  
            String r = m.group(1);  
            result.add(r);  
        }
        if(!result.isEmpty()){
        	return result.get(0);
        }
        return null; 
    }
	
	/**
	 * 
	 * 接口: 获取加载的所有的渠道服务
	 * @return
	 * @since 2017年11月14日
	 */
	public static Map<String, IQuickPayService> getPayServices(){
		Map<String, IQuickPayService> payServices = ContextUtils.getApplicationContext()
				.getBeansOfType(IQuickPayService.class);
		_log.info("所有的渠道服务[{}]", payServices);
		return payServices;
	}
	
	public static String subString(String amt) throws Exception {
		Assert.notNull(amt);
		return amt.substring(0, amt.lastIndexOf("."));
	}
}
